Virtualization is commonly used today to improve the performance and utilization of multi-core/multi-processor computer systems. In a virtualization environment, multiple virtual machines share the same physical hardware, such as processors/cores, memory and input/output (I/O) devices. A software layer called a hypervisor typically provides the virtualization, i.e., virtualization of physical processors, memory and peripheral devices. This technique thereby enables the sharing of hardware by multiple virtual machines.
A virtual machine can provide a complete system platform which supports the execution of a complete operating system. One of the advantages of virtual machine environments is that multiple operating systems (which may or may not be of the same type) can coexist on the same physical platform. In addition, a virtual machine can have an architecture that differs from that of the physical platform in which is implemented.
One problem often associated with virtualization environments is that there is no interface by which an application in a virtual machine can access high-performance (high-speed) devices at their native (or optimum) speed. In this context, high-performance devices may include, for example, network communication adapters such as Ethernet adapters and small computer system interface (SCSI) devices such as disk drives. This is in contrast with, for example, integrated drive electronics (IDE) devices, which in comparison to the aforementioned devices generally are relatively low-performance devices.
The cause of this problem is that the application does not have direct access to the device driver software within the virtual machine; there are several layers of software between them. This architecture has the advantage of enabling device-specific details to be hidden from the user space. However, because the application and the device driver may not be able to map each other's address spaces, they may not be able to share data with each other. In that case, communication of data between the application and the device driver involves making several copies of the data as it propagates through the various software layers (since the application and the device driver do not have any context about each other, yet data consistency needs to be preserved). Consequently, this process undesirably consumes additional CPU cycles to propagate the data through the various layers. Further, due to this copying, the data that reaches the destination software layer (i.e., the application or the device driver, depending on the direction of communication) often ends up on a completely different memory page from where it started at the source software layer (i.e., the device driver or the application), which is an inefficient use of memory.
In a particular implementation, a common problem associated with virtualization environments that provide device access via paravirtualization (PV) is a lack of flexibility when using PV interfaces. PV is a technique in which a virtual machine does not necessarily simulate hardware, but instead (or in addition) it offers a special application programming interface (API) that can only be used by modifying the guest application. In PV, the guest application is “aware” of the hypervisor, whereas in full virtualization the guest application is not aware of the hypervisor.
A PV interface is an idealized device interface that allows an application in a virtual machine to better access underlying devices. However, in PV, different hypervisors require different device drivers in the virtual machines; these device drivers within the virtual machines are called “front-end device drivers”. In order for the application to derive optimum performance from the PV device, the application might need to be modified. If the application is using an operating system API to access the PV device, the API might need to be modified instead. Effectively, therefore, custom modifications are needed inside the guest virtual machine to leverage the high-performance device.